package com.magicalcoder.pigeon.client;

import com.magicalcoder.pigeon.common.dto.RmtAddress;
import com.magicalcoder.pigeon.common.message.PigeonDecoder;
import com.magicalcoder.pigeon.common.message.PigeonEncoder;
import com.magicalcoder.pigeon.common.message.PigeonRequest;
import com.magicalcoder.pigeon.common.message.PigeonResponse;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetSocketAddress;
import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Created by hzhedongyu on 2017/5/27.
 * 线程连接池接受connect
 */
public class ClientConnectPool {

    private static Logger logger = LoggerFactory.getLogger(ClientConnectPool.class);

    private static ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(2,10,10, TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(2));

    public static void connect(RmtAddress rmtAddress){

        poolExecutor.execute(new Runnable() {
//            private int retryCount = 0;
            @Override
            public void run() {
                connectServer();
            }
            private void connectServer(){
                String randomId = UUID.randomUUID().toString();
                String host = rmtAddress.getHost();
                int port = rmtAddress.getPort();
                InetSocketAddress remotePeer = new InetSocketAddress(host, port);
                EventLoopGroup workerGroup = new NioEventLoopGroup();
                try {
                    Bootstrap b = new Bootstrap();
                    b.group(workerGroup)
                            .channel(NioSocketChannel.class)
                            .handler(new ChannelInitializer<SocketChannel>() {
                                @Override
                                protected void initChannel(SocketChannel socketChannel) throws Exception {
                                    ChannelPipeline cp = socketChannel.pipeline();
                                    cp.addLast(new PigeonEncoder(PigeonRequest.class));
                                    cp.addLast(new LengthFieldBasedFrameDecoder(65536, 0, 4, 0, 0));
                                    cp.addLast(new PigeonDecoder(PigeonResponse.class));

                                    NettyClientHandler handler = new NettyClientHandler(randomId,rmtAddress);
                                    cp.addLast(handler);
                                }
                            });

                    ChannelFuture channelFuture = b.connect(remotePeer);
                    channelFuture.addListener(new ChannelFutureListener() {
                        //当成功连接服务器时
                        @Override
                        public void operationComplete(final ChannelFuture channelFuture) throws Exception {
                            if (channelFuture.isSuccess()) {
                                NettyClientHandler handler = channelFuture.channel().pipeline().get(NettyClientHandler.class);
                                ClientHandlerManager.get().addHandler(handler);
                                logger.info("client 客户端启动成功");
                            }
                        }

                    });
                    channelFuture.channel().closeFuture().sync();
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    //回收handler
                    ClientHandlerManager.get().removeHandler(randomId);
                    workerGroup.shutdownGracefully();
                }
            }
        });
    }



}
